package com.ljw.http.client;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;


/**
 * @author liujw
 * @create 2020/10/15 09:47
 */
public class RestTemplateClient implements ApplicationContextAware {
    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        RestTemplateClient.applicationContext = applicationContext;
    }

    public static void main(String[] args) {
        String urlPath = "https://10.10.20.143:28000/cfgmgr/queryPolicy";

        Map<String, String> headers = new HashMap<>(2);
        headers.put("csrfTokenHoneypot", "1c7cd1dcec5bbf358dfe25a7f99a25dfcf8ef81c3eb19a638bdd5072a7c4c6d5bbd503d27ab310b3b3125b760451efe0f8af363728aeea0dabf83b2b26337a9559adef4fd4a59c2580d934368e8b2b09d904f1cd39e506c2d9fbfba4f265e4ef9cecbb997e97442beb3a523949239bdf212ac8d36b2adb259aaf10bb685b03e4b09ef6e404a83cb43a86d9d6bd377472a121e551d94840bef2042db15133937f34c762be7252b4fbb5f731b667951db15ed3a1e1ae983f776818f64f2a8a7b03a0794cb60defcd7709f2ef4e03186253fc93ff1a5001a3e96bca0e16d481ae1a23c4f7d72a833bfe001a0564a0d8d88c3a7656153a04c676ef6c5b741ee4f36a6a5f8b460ccf34726a30e9f569b74152");
        headers.put("Cookie", "JSESSIONID=7B6DC43C7FEBF504E7EFBB01D0C72F2E");
        headers.put("Content-Type", MediaType.APPLICATION_JSON.toString());
        headers.put("Charset", "UTF-8");

        String paramBody = "{\"currentPage\":1,\"pageSize\":1}";

        String result = send(urlPath, headers, paramBody, "POST");
        System.out.println(result);
    }

    private static String send(String urlPath, Map<String, String> headers, String paramBody, String method) {
        RestTemplate restTemplate = buildRestTemplate();

        HttpHeaders httpHeaders = null;
        if (headers != null && !headers.isEmpty()) {
            httpHeaders = new HttpHeaders();
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                String value = entry.getValue();
                if (StringUtils.isNotBlank(value)) {
                    httpHeaders.add(entry.getKey(), value);
                }
            }
        }

        ResponseEntity<String> responseEntity = null;
        if (HttpMethod.POST.matches(method)) {
            HttpEntity<String> httpEntity = new HttpEntity<>(paramBody, httpHeaders);
            responseEntity = restTemplate.postForEntity(urlPath, httpEntity, String.class);
            if (responseEntity.getStatusCode().is3xxRedirection()) {
                // 重定向
                responseEntity = restTemplate.postForEntity(responseEntity.getHeaders().getLocation(), httpEntity, String.class);
            }
        } else if (HttpMethod.GET.matches(method)) {
            HttpHeaders finalHttpHeaders = httpHeaders;
            restTemplate.setInterceptors(Collections.singletonList((httpRequest, bytes, clientHttpRequestExecution) -> {
                httpRequest.getHeaders().addAll(finalHttpHeaders);
                return clientHttpRequestExecution.execute(httpRequest, bytes);
            }));

            responseEntity = restTemplate.getForEntity(urlPath, String.class, (Map<String, ?>) null);
            if (responseEntity.getStatusCode().is3xxRedirection()) {
                // 重定向
                responseEntity = restTemplate.getForEntity(responseEntity.getHeaders().getLocation(), String.class);
            }
        } else {
            throw new RuntimeException("Method Not Support, method is" + method);
        }

        return responseEntity.getBody();
    }

    /**
     * 开放ssl认证
     * @return
     */
    private static RestTemplate buildRestTemplate() {
        CloseableHttpClient httpClient;
        try {
            httpClient = HttpClients.custom().setSSLSocketFactory(new SSLConnectionSocketFactory(SslUtil.buildSSLContext().getSocketFactory(), null, null, (s, sslSession) -> true)).build();
        } catch (NoSuchAlgorithmException | KeyManagementException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }

        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);

        RestTemplate restTemplate = new RestTemplate(requestFactory);
        return restTemplate;
    }
}
